package cn.easy.kitchen.service;

import cn.easy.base.bean.PageBean;
import cn.easy.base.service.BaseService;
import cn.easy.kitchen.bean.BomNutritionBean;
import cn.easy.kitchen.domain.Bom;
import cn.easy.kitchen.repository.BomDao;
import cn.easy.kitchen.utils.ProjectUtil;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class BomService extends BaseService<Bom> {
    @Autowired
    private BomDao	bomDao;
    @Autowired
    private EntityManager entityManager;

    public Page<Bom> search(Map<String, Object> searchParams, PageBean pageBean) {
        return bomDao.findAll(spec(searchParams), pageBean.toPageRequest(new Sort(Direction.DESC, "createdAt")));
    }

    public List<Bom> search(Map<String, Object> searchParams, Sort... sort) {
        return bomDao.findAll(spec(searchParams), sort == null || sort.length == 0  ? new Sort(Direction.DESC, "createdAt") : sort[0]);
    }
        
    public List<BomNutritionBean> searchByParams(Map<String, Object> searchParams) {
        StringBuilder sql = new StringBuilder("SELECT t.* FROM ( ");
        sql.append("SELECT base.id, base.name, t3.nut_name, ROUND(sum(t3.yingyang),2) AS yingyang ");
        sql.append("FROM ck_bom bom LEFT JOIN ck_material_base base ON bom.dest_material_id = base.id ");
        sql.append("LEFT JOIN (SELECT t1.dest_material_id AS dest_material_id, type.`name` AS nut_name, t1.src_material_weight * nut.content / 500 / 1000 AS yingyang ");
        sql.append("FROM ck_bom t1 LEFT JOIN ck_material_base t2 ON t1.src_material_id = t2.id LEFT JOIN ck_nutrition nut ON nut.material_base_id = t2.id ");
        sql.append("LEFT JOIN ck_nutrition_type type ON type.id = nut.nutrition_type_id ");
        sql.append("WHERE t1.bom_level = '二级' AND nut.content IS NOT NULL ) t3 ON bom.src_material_id = t3.dest_material_id ");
        sql.append("WHERE bom.bom_level = '一级'  and base.`name` not like '%禁用%'  GROUP BY base. NAME, t3.nut_name ) t WHERE t.yingyang IS NOT NULL ");

        int currentPage = (int) (Math.random() * 1400);
        if (currentPage < 100) {
            currentPage = 100;
        }
        sql.append("LIMIT " + (currentPage - 100) + "," + currentPage);

        Query query = entityManager.createNativeQuery(sql.toString());
        List<Object[]> list = query.getResultList();
        Map<String, String> traceElementMap = ProjectUtil.getTraceElementMap();
        Map<String, BomNutritionBean> resultMap = new HashMap<>();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Object[] ob = list.get(i);
                String materialBaseId = ob[0].toString();
                //只取前五个
                if (resultMap.size() == 5 &&
                        resultMap.containsKey(materialBaseId)) {
                    break;
                }
                String nutName = ob[2].toString();
                BigDecimal nutValue = ProjectUtil.getBigDecimalVal(ob[3]);
                BomNutritionBean nutritionBean = resultMap.get(materialBaseId);
                if (nutritionBean == null) {
                    nutritionBean = new BomNutritionBean();
                    nutritionBean.setName(ProjectUtil.cutStrLength(ob[1].toString(), 5));
                    nutritionBean.setTraceElement(BigDecimal.ZERO);
                }
                switch (nutName) {
                    case "蛋白质":
                        nutritionBean.setProtein(nutValue);
                        break;
                    case "脂肪":
                        nutritionBean.setFat(nutValue);
                        break;
                    case "糖":
                        nutritionBean.setSugar(nutValue);
                        break;
                    case "膳食纤维":
                        nutritionBean.setDietaryFiber(nutValue);
                        break;
                }
                //若属于微量元素,则累加
                if (traceElementMap.get(nutName) != null) {
                    nutritionBean.setTraceElement(nutritionBean.getTraceElement().add(nutValue));
                }
                resultMap.put(materialBaseId, nutritionBean);
            }
        }
        return new ArrayList<>(resultMap.values());
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void delete(String id) {
        bomDao.delete(id);
    }

    public Bom getOne(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        return bomDao.findOne(id);
    }

    public List<Bom> findAll(List<String> idList) {
        return Lists.newArrayList(bomDao.findAll(idList));
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Bom save(Bom bom) {
        return bomDao.save(bom);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void save(List<Bom> bomList) {
        bomDao.save(bomList);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteAll() {
        bomDao.deleteAll();
    }

    /**
     * 统计菜品种类
     * @return
     */
    public int countBom(){
        return bomDao.countBom();
    }
}


